
#include "TSintactico.h"


int TSintactico_Crear(TSintactico* as)
{
    as->codigoError = 0;
	as->longitud = 0;

}

int TSintactico_setError(TSintactico* as, int codigo, char* mensaje)
{
    int i = 0;
    as->codigoError = codigo;

    for(i=0;i<100;i++)
    {
        as->mensajeError[i] = mensaje[i];
    }

    return 0;
}

int TSintactico_getUltimoError(TSintactico* as, int* codigo, char* mensaje)
{
    int i = 0;

    *codigo = as->codigoError;

    for(i=0;i<100;i++)
    {
         mensaje[i] = as->mensajeError[i];
    }

}

int TSintactico_PushToken(TSintactico* as, Token* token)
{
	int i=0;

	as->tokens[as->longitud].tipo = token->tipo;

	for(i=0;i<MAX_DATO;i++)
		as->tokens[as->longitud].dato[i] = token->dato[i];

	as->longitud++;
}




void printAnidamiento(int anidamiento)
{

    int aux = 0;
    if (anidamiento>0)
    {
        for (aux=0;aux<anidamiento;aux++)
        {
            printf("    ");
        }
    }

}
void AnalizarArray(TSintactico *aSintactico, int *index,int anidamiento,Boolean esElValorDeUnaClave,Boolean *huboError);
void AnalizarObjeto(TSintactico *aSintactico, int *index,int anidamiento,Boolean *huboError);

int TSintactico_terminarFlujo(TSintactico* as)
{
	int index = 0;
	int anidamiento = 0;
	Boolean huboError = False;


	AnalizarObjeto(as, &index, anidamiento,&huboError);

	return True;
}




void AnalizarObjeto(TSintactico *aSintactico, int *index,int anidamiento,Boolean *huboError)
{
    int i = *index;
    Boolean yaSeImprimioClave = False;
    Boolean estaImprimiendoArray = False;


    Boolean seEsperaClave = False;
    Boolean seEsperaDosPuntos = False;
    Boolean seEsperaItem =False;

    int aux = 0;

    int borrar;



    printAnidamiento(anidamiento-1);


    anidamiento++;


    if(aSintactico->tokens[i].tipo == TOKEN_OBJETO_EMPIEZA)
    {
        seEsperaClave = True;
        printf("OBJETO\n");
        i++;
    }

    while((i<aSintactico->longitud) && (aSintactico->tokens[i].tipo != TOKEN_OBJETO_TERMINA) && (*huboError==False))
    {

        switch(aSintactico->tokens[i].tipo)
        {
            case TOKEN_OBJETO_EMPIEZA:
            {
                if (seEsperaClave)
                {
                    TSintactico_setError(aSintactico, 1, "Se esperaba clave");

                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }else if (seEsperaDosPuntos)
                {
                    TSintactico_setError(aSintactico,2, "Se esperaban dos puntos");

                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }
                else
                {
                    seEsperaClave = False;
                    seEsperaDosPuntos = False;
                    seEsperaItem = False;
                    AnalizarObjeto(aSintactico, &i,anidamiento+1,huboError);
                }
                break;
            }
            case TOKEN_DOSPUNTOS:
            {
                if (seEsperaClave)
                {
                    TSintactico_setError(aSintactico, 1, "Se esperaba clave");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }else if (seEsperaItem)
                {
                    TSintactico_setError(aSintactico, 3, "Se esperaba item");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }
                else
                {
                    seEsperaClave = False;
                    seEsperaDosPuntos = False;
                    seEsperaItem = True;

                    printf(": ");
                }


                break;
            }
            case TOKEN_STRING:
            {
                if (seEsperaDosPuntos)
                {
                    TSintactico_setError(aSintactico, 2, "Se esperaban dos puntos");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }
                else if (!yaSeImprimioClave)
                {
                    printAnidamiento(anidamiento);

                    printf("CLAVE: \"%s\"",aSintactico->tokens[i].dato);

                    yaSeImprimioClave = True;
                    seEsperaClave = False;
                    seEsperaItem = False;
                    seEsperaDosPuntos = True;
                }
                else
                {
                    seEsperaItem = False;

                    printf("(String): \"%s\"",aSintactico->tokens[i].dato);
                }

                break;
            }
            case TOKEN_NUMERO:
            {
                if (seEsperaClave)
                {
                    TSintactico_setError(aSintactico, 1, "Se esperaba clave");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }else if (seEsperaDosPuntos)
                {
                    TSintactico_setError(aSintactico, 2, "Se esperaban dos puntos");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }
                else
                {
                    seEsperaItem = False;
                    printf("(Numero) : %s",aSintactico->tokens[i].dato);
                }
                break;
            }
            case TOKEN_NULL:
            {
                if (seEsperaClave)
                {
                    TSintactico_setError(aSintactico, 1, "Se esperaba clave");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }else if (seEsperaDosPuntos)
                {
                    TSintactico_setError(aSintactico, 2, "Se esperaban dos puntos");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }
                else
                {
                    seEsperaItem = False;
                    printf("(Null) : ");
                }
                break;


            }
            case TOKEN_COMA:
            {

                if (seEsperaClave)
                {
                    TSintactico_setError(aSintactico, 1, "Se esperaba clave");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }else if (seEsperaDosPuntos)
                {
                    TSintactico_setError(aSintactico, 2, "Se esperaban dos puntos");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }
                else if (seEsperaItem)
                {
                    TSintactico_setError(aSintactico, 3, "Se esperaba item");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }
                else
                {
                    printf("\n");

                    seEsperaClave = True;
                    yaSeImprimioClave = False;
                }



                break;
            }
            case TOKEN_TRUE:
            {
                if (seEsperaClave)
                {
                    TSintactico_setError(aSintactico, 1, "Se esperaba clave");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }else if (seEsperaDosPuntos)
                {
                    TSintactico_setError(aSintactico, 2, "Se esperaban dos puntos");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }
                else
                {
                    seEsperaItem = False;
                    printf("(Boolean) : true");
                }

                break;
            }
            case TOKEN_FALSE:
            {
                if (seEsperaClave)
                {
                    TSintactico_setError(aSintactico, 1, "Se esperaba clave");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }else if (seEsperaDosPuntos)
                {
                    TSintactico_setError(aSintactico, 2, "Se esperaban dos puntos");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }
                else
                {
                    seEsperaItem = False;
                    printf("(Boolean) : false");
                }
                break;
            }

            case TOKEN_ERROR_LEXICO:
            {
                if (!yaSeImprimioClave)
                {
                    printAnidamiento(anidamiento);
                }

                printf("ERROR LEXICO");

                *huboError = True;
                break;
            }
            case TOKEN_ARRAY_EMPIEZA:
            {

                if (seEsperaClave)
                {
                    TSintactico_setError(aSintactico, 1, "Se esperaba clave");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }else if (seEsperaDosPuntos)
                {
                    TSintactico_setError(aSintactico, 2, "Se esperaban dos puntos");
                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }
                else
                {
                    seEsperaItem = False;
                    AnalizarArray(aSintactico, &i,anidamiento,yaSeImprimioClave,huboError);
                }
                break;
            }
        }

        i++;
    }

    anidamiento--;

    if((aSintactico->tokens[i].tipo == TOKEN_OBJETO_TERMINA) && (*huboError==False))
    {
        printf("\n");

        printAnidamiento(anidamiento-1);
        printf("FIN OBJETO");
    }

    *index = i;
}

void AnalizarArray(TSintactico *aSintactico, int *index,int anidamiento,Boolean esElValorDeUnaClave,Boolean *huboError)
{

    int i = *index;
    int aux = 0;

    Boolean seEsperaItem = False;

    if(esElValorDeUnaClave)
        anidamiento = anidamiento + 7;


    if(aSintactico->tokens[i].tipo == TOKEN_ARRAY_EMPIEZA)
    {
        if (esElValorDeUnaClave)
            printf("(Array): ARRAY\n");
        else
        {
            printAnidamiento(anidamiento-1);
            printf("ARRAY\n");
        }


        i++;
    }

    anidamiento++;

    while((i<aSintactico->longitud) && (aSintactico->tokens[i].tipo != TOKEN_ARRAY_TERMINA) && (*huboError==False) )
    {

        switch(aSintactico->tokens[i].tipo)
        {
            case TOKEN_ARRAY_EMPIEZA:
            {
                seEsperaItem = False;
                AnalizarArray(aSintactico, &i,anidamiento,False,huboError);

                break;
            }
            case TOKEN_OBJETO_EMPIEZA:
            {
                seEsperaItem = False;
                AnalizarObjeto(aSintactico, &i,anidamiento+1,huboError);
                break;
            }
            case TOKEN_STRING:
            {
                seEsperaItem = False;
                printAnidamiento(anidamiento);
                printf("(String): \"%s\"",aSintactico->tokens[i].dato);

                break;
            }
            case TOKEN_NUMERO:
            {
                seEsperaItem = False;
                printAnidamiento(anidamiento);
                printf("(Numero) : %s",aSintactico->tokens[i].dato);
                break;
            }

            case TOKEN_ERROR_LEXICO:
            {
                seEsperaItem = False;
                printAnidamiento(anidamiento);
                printf("ERROR LEXICO");

                 *huboError = True;
                break;
            }
            case TOKEN_COMA:
            {
                if (seEsperaItem)
                {
                    TSintactico_setError(aSintactico, 3, "Se esperaba item");

                    printAnidamiento(anidamiento);
                    printf("ERROR SINTACTICO");

                    *huboError = True;
                }
                else
                {
                    seEsperaItem = True;
                    printf("\n");
                }

                break;
            }

            case TOKEN_NULL:
            {
                seEsperaItem = False;
                printAnidamiento(anidamiento);
                printf("(Null) : ");
                break;
            }

            case TOKEN_TRUE:
            {
                seEsperaItem = False;
                printAnidamiento(anidamiento);
                printf("(Boolean) : true");
                break;
            }
            case TOKEN_FALSE:
            {
                seEsperaItem = False;
                printAnidamiento(anidamiento);
                printf("(Boolean) : false");
                break;
            }
        }

        i++;
    }

    if (seEsperaItem)
    {
        TSintactico_setError(aSintactico, 3, "Se esperaba item");
        printAnidamiento(anidamiento);
        printf("ERROR SINTACTICO");

         *huboError = True;
    }

    if((aSintactico->tokens[i].tipo == TOKEN_ARRAY_TERMINA) && (*huboError==False))
    {
        if (!esElValorDeUnaClave)
            anidamiento--;

       printf("\n");
       printAnidamiento(anidamiento-1);
       printf("FIN ARRAY");
    }

    *index = i;
}


